ADD_DEFINITIONS(${SIMD_FLAGS})

IF(PNG_FOUND)
    SET(CARINA_OPTIONAL_FEATURES_SRC ${CARINA_OPTIONAL_FEATURES_SRC}
        png-loader.cc)
    SET(CARINA_OPTIONAL_FEATURES_INC ${CARINA_OPTIONAL_FEATURES_INC} 
        ${CARINA_ENGINE_DIR}/include/carina/png-loader.hh)
    SET(ADDITIONAL_INC ${PNG_INCLUDE_DIRS})
    SET(ADDITIONAL_LIB_DIRS ${PNG_LIBRARY})
    SET(ADDITIONAL_LIBS ${PNG_LIBRARIES})
ENDIF()

FIND_PACKAGE(BISON REQUIRED)
FIND_PACKAGE(FLEX REQUIRED)

BISON_TARGET(CSPParser "${CMAKE_CURRENT_SOURCE_DIR}/csp.y"
             "${CMAKE_CURRENT_BINARY_DIR}/csp-parser.cc" 
             VERBOSE "${CMAKE_CURRENT_BINARY_DIR}/csp-parser.output"
             COMPILE_FLAGS "--report=state")
FLEX_TARGET(CSPScanner "${CMAKE_CURRENT_SOURCE_DIR}/csp.l"
            "${CMAKE_CURRENT_BINARY_DIR}/csp-scanner.cc"
            COMPILE_FLAGS "-Pcsp_")
ADD_FLEX_BISON_DEPENDENCY(CSPScanner CSPParser)

BISON_TARGET(ConfigParser "${CMAKE_CURRENT_SOURCE_DIR}/carina-config.y"
             "${CMAKE_CURRENT_BINARY_DIR}/carina-config-parser.cc" 
             VERBOSE "${CMAKE_CURRENT_BINARY_DIR}/carine-config-parser.output"
             COMPILE_FLAGS "--report=state")
FLEX_TARGET(ConfigScanner "${CMAKE_CURRENT_SOURCE_DIR}/carina-config.l"
            "${CMAKE_CURRENT_BINARY_DIR}/carina-config-scanner.cc"
            COMPILE_FLAGS "-Pcconf_")
ADD_FLEX_BISON_DEPENDENCY(ConfigScanner ConfigParser)

SET(BISON_GENERATED_INC
    ${CMAKE_CURRENT_BINARY_DIR}/location.hh
    ${CMAKE_CURRENT_BINARY_DIR}/position.hh)

#FILE(COPY ${BISON_GENERATED_INC}
#     DESTINATION  ${CMAKE_BINARY_DIR}/carina_engine/include/)


IF(UNIX)
    FIND_PACKAGE(OpenGL REQUIRED)
    SET(OPENGL_SUPPORT TRUE)
ELSE()
    FIND_PACKAGE(OpenGL)
    IF(BISON_FOUND AND FLEX_FOUND AND OPENGL_FOUND)
        SET(OPENGL_SUPPORT TRUE)
    ENDIF()
ENDIF()

BISON_TARGET(CarinaParser "${CMAKE_CURRENT_SOURCE_DIR}/carina-effect.y"
             "${CMAKE_CURRENT_BINARY_DIR}/carina-effect-parser.cc"
             VERBOSE "${CMAKE_CURRENT_BINARY_DIR}/carina-effect-parser.output"
             COMPILE_FLAGS "--report=state")
FLEX_TARGET(CarinaScanner "${CMAKE_CURRENT_SOURCE_DIR}/carina-effect.l"
            "${CMAKE_CURRENT_BINARY_DIR}/carina-effect-scanner.cc"
            COMPILE_FLAGS "-Pglfx_")
ADD_FLEX_BISON_DEPENDENCY(CarinaScanner CarinaParser)

IF(OPENGL_SUPPORT)
    SET(GRAPHICS_INC ${OPENGL_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
    ADD_DEFINITIONS(-DHAS_OPENGL)
    SET(CARINA_GL_INC
        ${CARINA_ENGINE_DIR}/include/carina/gl-window-impl.hh
        ${CARINA_ENGINE_DIR}/include/carina/gl-library.hh
        ${CARINA_ENGINE_DIR}/include/carina/gl-renderer.hh
        ${BISON_GLFXParser_OUTPUT_HEADER}
       )
    SET(CARINA_GL_SRC 
        gl-library.cc
        gl-renderer.cc
        gl-wrapper.cc
       )
    IF(UNIX)
        SET(CARINA_GL_SRC ${CARINA_GL_SRC} gl-window-impl-x11.cc)
    ELSE()
        SET(CARINA_GL_SRC ${CARINA_GL_SRC} gl-window-impl-w32.cc)
    ENDIF()
ENDIF()

FIND_PACKAGE(DirectX)

IF(DIRECTX_FOUND)
    SET(GRAPHICS_INC ${GRAPHICS_INC} ${DIRECT3D_INCLUDE_DIR} ${D3D_EXT_EFFECTS11_INCLUDE_DIR})
    SET(CARINA_DX_INC
        ${CARINA_ENGINE_DIR}/include/carina/dx-window-impl.hh
        ${CARINA_ENGINE_DIR}/include/carina/dx-renderer.hh
        ${CARINA_ENGINE_DIR}/include/carina/dx-library.hh
       )
    SET(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${D3D_EXT_EFFECTS11_LIBRARY} ${D3D_COMPILER_LIBRARY})
    SET(CARINA_DX_SRC
        dx-window-impl-w32.cc
        dx-library.cc
        dx-renderer.cc
        dx-wrapper.cc
       )
    IF(NOT MSVC)
        ADD_DEFINITIONS("-fcheck-new" "-Wno-unknown-pragmas")
    ENDIF(NOT MSVC)
    ADD_DEFINITIONS(-DHAS_D3D)
ELSE(NOT DIRECTX_FOUND)    
    IF(NOT OPENGL_SUPPORT)
        MESSAGE(FATAL_ERROR "DirectX and/or OpenGL are required for compiling this application")
    ENDIF()
ENDIF(DIRECTX_FOUND)

IF(WIN32)
    SET(CARINA_PLATFORM_SPECIFIC_SRC window-w32.cc)
    SET(CARINA_PLATFORM_SPECIFIC_INC
        ${CARINA_ENGINE_DIR}/include/carina/window-w32.hh
        )
ELSEIF(UNIX)
    SET(PLATFORM_SPECIFIC_INC ${X11_INCLUDE_DIR})
    SET(PLATFORM_SPECIFIC_LIBS pthread rt ${X11_LIBRARIES})

    SET(CARINA_PLATFORM_SPECIFIC_SRC window-x11.cc)
    SET(CARINA_PLATFORM_SPECIFIC_INC
        ${CARINA_ENGINE_DIR}/include/carina/window-x11.hh
        )
ELSE()
    MESSAGE(FATAL_ERROR "unsupported platform")
ENDIF()

LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}
                 ${ADDITIONAL_LIB_DIRS})
INCLUDE_DIRECTORIES(${CARINA_ENGINE_INCLUDE_DIRS}
                ${Boost_INCLUDE_DIRS} 
                ${FREETYPE_INCLUDE_DIRS}
                ${GRAPHICS_INC}
                ${PLATFORM_SPECIFIC_INC}
				${CMAKE_CURRENT_SOURCE_DIR}
                ${ADDITIONAL_INC})

SET(CARINA_INCLUDES 
    ${CARINA_ENGINE_DIR}/include/carina/camera.hh
    ${CARINA_ENGINE_DIR}/include/carina/debug-gui.hh
    ${CARINA_ENGINE_DIR}/include/carina/filters.hh
    ${CARINA_ENGINE_DIR}/include/carina/image.hh
    ${CARINA_ENGINE_DIR}/include/carina/library.hh
    ${CARINA_ENGINE_DIR}/include/carina/material-manager.hh
    ${CARINA_ENGINE_DIR}/include/carina/math.hh
    ${CARINA_ENGINE_DIR}/include/carina/mesh.hh
    ${CARINA_ENGINE_DIR}/include/carina/resources.hh
    ${CARINA_ENGINE_DIR}/include/carina/scene.hh
    ${CARINA_ENGINE_DIR}/include/carina/terrain.hh
    ${CARINA_ENGINE_DIR}/include/carina/utils.hh
    ${CARINA_ENGINE_DIR}/include/carina/renderer-base.hh
    ${CARINA_ENGINE_DIR}/include/carina/axis.hh
    ${CARINA_ENGINE_DIR}/include/carina/window.hh
    ${CARINA_ENGINE_DIR}/include/carina/settings-file.hh
    ${CARINA_ENGINE_DIR}/include/carina/graphics-engine.hh
    ${CARINA_ENGINE_DIR}/include/carina/ces-loader.hh
    ${CARINA_ENGINE_DIR}/include/carina/file-system.hh
    ${CARINA_ENGINE_DIR}/include/carina/lighting.hh
    ${CARINA_ENGINE_DIR}/include/carina/collision-detection.hh
    ${CARINA_ENGINE_DIR}/include/carina/world-manager.hh
    ${CARINA_ENGINE_DIR}/include/carina/box.hh
    ${CARINA_ENGINE_DIR}/include/carina/attribute.hh
    ${CARINA_ENGINE_DIR}/include/carina/node-manager.hh
    ${CARINA_ENGINE_DIR}/include/carina/tga-loader.hh
    ${CARINA_ENGINE_DIR}/include/carina/ast.hh
    ${CARINA_ENGINE_DIR}/include/carina/csp-ast.hh
    ${CARINA_ENGINE_DIR}/include/carina/csp-driver.hh
    ${CARINA_ENGINE_DIR}/include/carina/shader-program.hh
    ${CARINA_ENGINE_DIR}/include/carina/post-processing.hh
    ${CARINA_ENGINE_DIR}/include/carina/carina-config-ast.hh
    ${CARINA_ENGINE_DIR}/include/carina/carina-config-driver.hh
    ${CARINA_ENGINE_DIR}/include/carina/carina-effect-driver.hh
    ${CARINA_ENGINE_DIR}/include/carina/carina-effect-ast.hh
    ${CARINA_ENGINE_DIR}/include/carina/carina-effect-common.hh
    ${CARINA_ENGINE_DIR}/include/carina/gl-effect-generator.hh
    ${CARINA_ENGINE_DIR}/include/carina/dx-effect-generator.hh
    ${CARINA_PLATFORM_SPECIFIC_INC}
    ${CARINA_OPTIONAL_FEATURES_INC}
    ${CARINA_GL_INC}
    ${CARINA_DX_INC}
    )

SOURCE_GROUP("Carina Engine Includes" FILES ${CARINA_INCLUDES})

SET(CARINA_GENERAL_SRC  
    math.cc 
    math-matrix.cc
    image.cc
    material-manager.cc
    resources.cc 
    mesh.cc 
    camera.cc 
    debug-gui.cc
    filters.cc  
    scene.cc 
    terrain.cc
    renderer-base.cc
    library.cc
    axis.cc
    settings-file.cc
    graphics-engine.cc
    ces-loader.cc
    file-system.cc
    lighting.cc
    collision-detection.cc
    world-manager.cc
    box.cc
    attribute.cc
    node-manager.cc
    tga-loader.cc
    ast.cc
    csp.y
    csp.l
    csp-ast.cc
    csp-driver.cc
    shader-program.cc
    post-processing.cc
    carina-config.y
    carina-config.l
    carina-config-ast.cc
    carina-config-driver.cc
    carina-effect.y
    carina-effect.l
    carina-effect-common.cc
    carina-effect-ast.cc
    carina-effect-driver.cc
    dx-effect-generator.cc
    gl-effect-generator.cc
    ${CMAKE_CURRENT_BINARY_DIR}/carina-effect-parser.cc
    ${CMAKE_CURRENT_BINARY_DIR}/carina-effect-scanner.cc
    ${CMAKE_CURRENT_BINARY_DIR}/csp-parser.cc
    ${CMAKE_CURRENT_BINARY_DIR}/csp-scanner.cc
    ${CMAKE_CURRENT_BINARY_DIR}/carina-config-parser.cc
    ${CMAKE_CURRENT_BINARY_DIR}/carina-config-scanner.cc
    ${CARINA_PLATFORM_SPECIFIC_SRC}
    ${CARINA_OPTIONAL_FEATURES_SRC}
    ${CARINA_GL_SRC}
    ${CARINA_DX_SRC}
    )
SOURCE_GROUP("Carina Engine General" FILES ${CARINA_GENERAL_SRC})

IF(MINGW)
    # Because this breaks packing and you should never ever use bitfield. They may cause some arcane multithreading bugs and they are quite annoying when
    # you run on platforms with different endianness.
    ADD_DEFINITIONS(-mno-ms-bitfields)
ENDIF()

ADD_LIBRARY(carina_engine STATIC ${CARINA_INCLUDES} ${CARINA_GENERAL_SRC})

IF(MSVC OR MINGW)
    TARGET_LINK_LIBRARIES(carina_engine carina_common ${PLATFORM_SPECIFIC_LIBS} ${FREETYPE_LIBRARIES} ${Boost_LIBRARIES} ${ADDITIONAL_LIBS} ${CARINA_DEBUG_LIBRARIES})
ELSEIF(UNIX)
    TARGET_LINK_LIBRARIES(carina_engine carina_common ${PLATFORM_SPECIFIC_LIBS} -Wl,-Bstatic -Wl,-Bdynamic ${FREETYPE_LIBRARIES} ${Boost_LIBRARIES} ${ADDITIONAL_LIBS} ${CARINA_DEBUG_LIBRARIES})
ELSE()
	MESSAGE(FATAL_ERROR "Unsupported platform")
ENDIF()

ADD_LIBRARY(carina_engine_silent STATIC ${CARINA_INCLUDES} ${CARINA_GENERAL_SRC})

IF(MSVC OR MINGW)
    TARGET_LINK_LIBRARIES(carina_engine_silent carina_common_silent ${PLATFORM_SPECIFIC_LIBS} ${FREETYPE_LIBRARIES} ${Boost_LIBRARIES} ${ADDITIONAL_LIBS} ${CARINA_DEBUG_LIBRARIES})
ELSEIF(UNIX)
    TARGET_LINK_LIBRARIES(carina_engine_silent carina_common_silent ${PLATFORM_SPECIFIC_LIBS} -Wl,-Bstatic -Wl,-Bdynamic ${FREETYPE_LIBRARIES} ${Boost_LIBRARIES} ${ADDITIONAL_LIBS} ${CARINA_DEBUG_LIBRARIES})
ELSE()
	MESSAGE(FATAL_ERROR "Unsupported platform")
ENDIF()

INSTALL(TARGETS carina_engine DESTINATION lib)
